package com.codegen.entity;

import com.codegen.enums.DefaultOperate;
import com.codegen.enums.FieldType;
import com.codegen.handler.ExtendedFieldHandler;
import com.codegen.handler.TableFieldHandler;
import com.codegen.handler.TableOperateHandler;
import com.codegen.utils.AppException;
import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.WordUtils;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author LZCXTECH06
 * @date 2019年9月10日
 */
@Data
public class Table {
    /**
     * 表格名称
     */
    @NotBlank(message = "表格名称不能为空")
    private String tableName;
    /**
     * 表格的描述
     */
    @NotBlank(message = "表格描述不能为空")
    private String tableDesc;

    @NotBlank(message = "报名不可为空")
    private String packageName;
    /**
     * 模块名称
     */
    @NotBlank(message = "项目模块名称不能为空", groups = {Add.class, Edit.class})
    private String moduleName;

    /**
     * 表格的前缀（会在前面添加前缀，比如创建的tableName = "user",如果tablePrefix="tb_",那么数据库表明就是tb_user）
     */
    @NotBlank(message = "表格前缀不能为空", groups = {TableGenParam.Add.class, TableGenParam.Edit.class})
    private String tablePrefix;
    /**
     * 主键策略
     */
    @NotBlank(message = "主键策略不能为空")
    private String pkStrategy;

    /**
     * 表格是否可以分页
     */
    private Boolean pageable;

    /**
     * 表类型
     *
     * @see com.codegen.enums.RelationType
     */
    private String relationType;
    /**
     * 表明该表类型的关键字段
     * <br/> 表明该表结构是否需要relationField字段 =>RelationType#needFk
     */
    private String relationField;

    /**
     * 表单布局类型
     *
     * @see com.codegen.enums.FormLayout
     */
    private String formLayout;

    /**
     * 列表布局类型左树右表、表格、
     *
     * @see com.codegen.enums.ListLayout
     */
    private String listLayout;

    /**
     * 表格的字段
     */
    @com.baomidou.mybatisplus.annotation.TableField(typeHandler = TableFieldHandler.class)
    private List<TableField> tableFields;

    /**
     * 表格允许的操作：比如新增，删除，修改，导入，导出等等
     */
    @com.baomidou.mybatisplus.annotation.TableField(typeHandler = TableOperateHandler.class)
    private List<TableOperate> tableOperates;

    /**
     * 非数据库的扩展字段
     */
    @com.baomidou.mybatisplus.annotation.TableField(typeHandler = ExtendedFieldHandler.class)
    private List<Field> extendedFields;


    /**
     * 生成的数据库的表名
     *
     * @return
     */
    public String getDbTableName() {
        return getTablePrefix() + getTableName();
    }


    @JsonIgnore
    public String getClassName() {
        return WordUtils.capitalizeFully(tableName, new char[]{'_'}).replace("_", "");
    }

    @JsonIgnore
    public boolean getHasDateField() {
        if (CollectionUtils.isNotEmpty(tableFields)) {
            for (TableField tableField : tableFields) {
                if (FieldType.DATETIME == tableField.getFieldType()) {
                    return true;
                }
            }
        }
        return false;
    }

    public String getPrimaryKeys() {
        if (CollectionUtils.isNotEmpty(tableFields)) {
            List<String> pks = new ArrayList<String>();
            for (TableField tableField : tableFields) {
                if (tableField.isPk()) {
                    pks.add(tableField.getName());
                }
            }
            if (CollectionUtils.isNotEmpty(pks)) {
                return StringUtils.join(pks, ",");
            }
        }
        return null;
    }


    /**
     * 是否有导出操作
     *
     * @return
     */
    @JsonIgnore
    public boolean getHasExportOperate() {
        if (CollectionUtils.isNotEmpty(tableOperates)) {
            return false;
        }
        for (TableOperate operate : tableOperates) {
            if (operate.getName().equals(DefaultOperate.EXPROT.getName())) {
                return true;
            }
        }
        return false;
    }

    /**
     * 是否有导入操作
     *
     * @return
     */
    @JsonIgnore
    public boolean getHasImportOperate() {
        if (CollectionUtils.isNotEmpty(tableOperates)) {
            return false;
        }
        for (TableOperate operate : tableOperates) {
            if (operate.getName().equals(DefaultOperate.IMPORT.getName())) {
                return true;
            }
        }
        return false;
    }

    @JsonIgnore
    public FieldType getPkType() {
        for (TableField tableField : tableFields) {
            if (tableField.isPk()) {
                return tableField.getFieldType();
            }
        }
        throw new AppException("未找到主键类型");
    }

    public String getPathName() {
        return tableName.replace("_", "/");
    }

    /**
     * 列表是否需要多选按钮列
     *
     * @return
     */
    @JsonIgnore
    public boolean getMulSelectable() {
        if (CollectionUtils.isNotEmpty(tableOperates)) {
            return false;
        }
        for (TableOperate operate : tableOperates) {
            if (operate.isBatchable()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 获取关联的表 获取表格相关的关联表字段
     *
     * @return
     */
    @JsonIgnore
    public List<TableRef> getTableRefs() {
        if (CollectionUtils.isNotEmpty(tableFields)) {
            return Collections.emptyList();
        }
        List<TableRef> refs = new ArrayList<>();
        for (TableField tableField : tableFields) {
            TableRef tmp = tableField.getRef();
            if (null != tmp) {
                refs.add(tableField.getRef());
            }
        }
        return refs;
    }

    public interface Add {
    }

    ;

    public interface Edit {
    }

    ;
}
